/*
 *      SObject.cpp
 *
 *      Copyright 2009 virpool <virpool@ukrpost.ua>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#include "SObject.h"
#include "SClassString.h"
#include "SClassInteger.h"
#include "SClassFloat.h"

SObject::SObject(string name, string classname)
{
	this->name = name;
	this->classname = classname;
	methods.insert(pair<string, s_func>("ToString", &SObject::DefToString));
	methods.insert(pair<string, s_func>("ClassName", &SObject::ClassName));
}

SObject::~SObject()
{
	methods.clear();
}

int SObject::DefToString(SObject *obj, s_param *res, list<s_param> *args)
{
	if ( res )
	{
		res->val = &obj->name;
		res->type = S_STRING;
	}
	return S_INVOKE_OK;
}

int SObject::ClassName(SObject *obj, s_param *res, list<s_param> *args)
{
	if ( res )
		{
			res->val = &obj->classname;
			res->type = S_STRING;
		}
	return S_INVOKE_OK;
}

int SObject::AddMethod(SObject *obj, string name, s_func func)
{
	map<string, s_func>::iterator p = obj->GetMethods()->find(name);
	if (p != obj->GetMethods()->end())
	{
		return S_METHOS_DUBLICATE;
	}
	obj->GetMethods()->insert(pair<string, s_func>(name, func));
	return S_ADD_METHOD_OK;
}

int SObject::Invoke(string method, s_param *result, list<s_param> *args)
{
	map<string, s_func>::iterator p = methods.find(method);
	if (p == methods.end())
	{
		return S_INVOKE_NOMETHOD;
	}
	return (*p->second)(this, result, args);
}

bool SObject::operator > (const SObject *a)
{
	if (classname == "String")
	{
		return ((SClassString*)this)->Get() > ((SClassString*)a)->Get();
	}
	else if (classname == "Integer")
	{
		return ((SClassInteger*)this)->Get() > ((SClassInteger*)a)->Get();
	}
	else if (classname == "Float")
	{
		return ((SClassFloat*)this)->Get() > ((SClassFloat*)a)->Get();
	}
	return false;
}

bool SObject::operator < (const SObject *a)
{
	if (classname == "String")
	{
		return ((SClassString*)this)->Get() < ((SClassString*)a)->Get();
	}
	else if (classname == "Integer")
	{
		return ((SClassInteger*)this)->Get() < ((SClassInteger*)a)->Get();
	}
	else if (classname == "Float")
	{
		return ((SClassFloat*)this)->Get() < ((SClassFloat*)a)->Get();
	}
	return false;
}

bool SObject::operator == (const SObject *a)
{
	if (classname == "String")
	{
		return ((SClassString*)this)->Get() == ((SClassString*)a)->Get();
	}
	else if (classname == "Integer")
	{
		return ((SClassInteger*)this)->Get() == ((SClassInteger*)a)->Get();
	}
	else if (classname == "Float")
	{
		return ((SClassFloat*)this)->Get() == ((SClassFloat*)a)->Get();
	}
	return false;
}
